import 'core-js/stable';
import 'regenerator-runtime/runtime';

import { Component } from './core/component.js';
import { Router } from './router/index.js';
import { Store } from './store/index.js';
import { compileComponentFile } from './compiler/componentCompiler.js';

class MiniApp {
  constructor(options) {
    this.$options = options;
    this.$router = options.router;
    this.$store = options.store;

    this.init();
  }

  init() {
    const rootComponent = new Component(this.$options);
    document.querySelector(this.$options.el).appendChild(rootComponent.$el);
  }

  async component(name, options) {
    const compiledOptions = await compileComponentFile(options);
    return (slots, scopedSlots) => new Component(Object.assign({}, compiledOptions, { slots, scopedSlots }));
  }

  static use(plugin, options) {
    if (typeof plugin.install === 'function') {
      plugin.install(MiniApp, options);
    } else if (typeof plugin === 'function') {
      plugin(MiniApp, options);
    }
  }

  asyncComponent(loadFunction) {
    return {
      component: null,
      loading: true,
      error: null,
      loadComponent: async () => {
        try {
          const component = await loadFunction();
          this.component = component;
          this.loading = false;
        } catch (err) {
          this.error = err;
          this.loading = false;
        }
      }
    };
  }

  static config(options) {
    if (options.errorHandler) {
      window.onerror = function(message, source, lineno, colno, error) {
        options.errorHandler(error, this);
      };
    }
  }
}

export { MiniApp, Component, Router, Store };